package cn.unknownerror.ueteam.data;

import org.bukkit.Bukkit;

import javax.swing.plaf.nimbus.State;
import java.io.File;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class SQLiteUnit implements StorageUnit{
    private String dbFilePath;

    public SQLiteUnit(String dbFilePath){
        this.dbFilePath = dbFilePath;
        try {
            Connection c= getConnection();
            Statement statement = c.createStatement();
            String sql = "CREATE TABLE IF NOT EXISTS TEAM " +
                    "(" +
                    " UUID    TEXT PRIMARY KEY   NOT NULL, " +
                    " V           TEXT     NOT NULL " +
                    ");";
            statement.executeUpdate(sql);
            sql = "CREATE TABLE IF NOT EXISTS PTT " +
                    "(" +
                    " PUUID   TEXT  PRIMARY KEY  NOT NULL, " +
                    " TUUID       TEXT" +
                    ");";
            statement.executeUpdate(sql);
            statement.close();
            c.close();
        } catch ( Exception e ) {
            Bukkit.getServer().getLogger().warning(e.toString());
            for(StackTraceElement element : e.getStackTrace()){
                Bukkit.getServer().getLogger().warning(element.toString());
            }
        }
    }

    private Connection getConnection() throws ClassNotFoundException, SQLException {
        Connection conn = null;
        Class.forName("org.sqlite.JDBC");
        conn = DriverManager.getConnection("jdbc:sqlite:" + dbFilePath);
        return conn;
    }

    private boolean hasRecord(Statement statement,String table, String key, String value){
        boolean result = false;
        ResultSet rs = null;
        try {
            rs = statement.executeQuery("SELECT * FROM "+table+" WHERE "+key+" = '"+value+"';");
            while(rs.next()){
                result = true;
            }
        } catch (SQLException e) {
            Bukkit.getServer().getLogger().warning(e.toString());
            for(StackTraceElement element : e.getStackTrace())
                Bukkit.getServer().getLogger().info(element.toString());
        }
        return result;
    }

    public void setDbFilePath(String dbFilePath) {
        this.dbFilePath = dbFilePath;
    }

    @Override
    public void saveTeamData(Data data) {
        try {
            Connection c = getConnection();
            c.createStatement().executeUpdate("DELETE FROM TEAM");
            String sql;
            PreparedStatement statement;
            UUID uuid =data.getUUID("uuid");
            if(hasRecord(c.createStatement(),"TEAM","UUID",uuid.toString())){
                sql= "UPDATE TEAM SET UUID = ?, V = ? WHERE UUID = '"+uuid.toString()+"';";
            }else{
                sql = "INSERT INTO TEAM (UUID, V) VALUES (?, ?);";
            }
            statement= c.prepareStatement(sql);
            statement.setString(1,uuid.toString());
            statement.setString(2,data.toString());
            statement.executeUpdate();
            statement.close();
            c.close();
        } catch (Exception e){
            Bukkit.getServer().getLogger().warning(e.toString());
            for(StackTraceElement element : e.getStackTrace()){
                Bukkit.getServer().getLogger().warning(element.toString());
            }
        }
    }

    @Override
    public void savePTT(Data data) {
        try {
            Connection c = getConnection();
            c.createStatement().executeUpdate("DELETE FROM PTT");
            String sql;
            PreparedStatement statement;
            for(String puuid:data.getKeySet()){
                if(hasRecord(c.createStatement(),"PTT","PUUID",puuid)){
                    sql= "UPDATE PTT SET PUUID = ?, TUUID = ? WHERE PUUID = '"+puuid+"';";
                }else{
                    sql = "INSERT INTO PTT (PUUID, TUUID) VALUES (?, ?);";
                }
                statement= c.prepareStatement(sql);
                statement.setString(1,puuid);
                statement.setString(2,data.getString(puuid));
                statement.executeUpdate();
                statement.close();
            }
            c.close();
        } catch (Exception e){
            Bukkit.getServer().getLogger().warning(e.toString());
            for(StackTraceElement element : e.getStackTrace()){
                Bukkit.getServer().getLogger().warning(element.toString());
            }
        }
    }

    @Override
    public Data getTeamData(String uuid) {
        try {
            Connection c=getConnection();
            Statement statement = c.createStatement();
            ResultSet rs = statement.executeQuery( "SELECT V FROM TEAM WHERE UUID = '"+uuid+"';" );
            rs.next();
            Data data = Data.fromString(rs.getString("V"));
            rs.close();
            statement.close();
            c.close();
            return data;
        } catch (Exception e){
            Bukkit.getServer().getLogger().warning(e.toString());
            for(StackTraceElement element : e.getStackTrace()){
                Bukkit.getServer().getLogger().warning(element.toString());
            }
        }
        return null;
    }

    @Override
    public List<Data> getTeamData() {
        try {
            Connection c=getConnection();
            Statement statement = c.createStatement();
            ResultSet rs = statement.executeQuery( "SELECT V FROM TEAM;" );
            List<Data> list = new ArrayList<>();
            while (rs.next()){
                list.add(Data.fromString(rs.getString("V")));
            }
            rs.close();
            statement.close();
            c.close();
            return list;
        } catch (Exception e){
            Bukkit.getServer().getLogger().warning(e.toString());
            for(StackTraceElement element : e.getStackTrace()){
                Bukkit.getServer().getLogger().warning(element.toString());
            }
        }
        return null;
    }

    @Override
    public Data getPTT() {
         try {
             Data data = new Data();
            Connection c=getConnection();
            Statement statement = c.createStatement();
            ResultSet rs = statement.executeQuery( "SELECT * FROM PTT;" );
            while(rs.next()){
                data.put(rs.getString("PUUID"),rs.getString("TUUID"));
            }
            rs.close();
            statement.close();
            c.close();
            return data;
        } catch (Exception e){
            Bukkit.getServer().getLogger().warning(e.toString());
            for(StackTraceElement element : e.getStackTrace()){
                Bukkit.getServer().getLogger().warning(element.toString());
            }
        }
         return null;
    }
}
